 <?php
/**
 * 区域模型
 * BaseAreaModel.php
 * ==============================================
 * 版权所有 2013-2014
 * ----------------------------------------------
 * 这不是一个自由软件，未经授权不许任何使用和传播。
 * ----------------------------------------------
 * 
 * @package xcs
 * @author Huangdaohai
 * @email huangdaohai.2007@163.com
 * @version $Id$
 * @access public
 */
class BaseAreaModel extends BaseModel  implements DictJsCacheInterface 
{
	/**
	 * Returns the static model of the specified AR class.
	 * @param string $className active record class name.
	 * @return AreaModel the static model class
	 */
	
	
	public static function model($className=__CLASS__)
	{
		return parent::model($className);
	}

	/**
	 * @return string the associated database table name
	 */
	public function tableName()
	{
		return '{{base_area}}';
	}

	/**
	 * @return array validation rules for model attributes.
	 */
	public function rules()
	{
		// NOTE: you should only define rules for those attributes that
		// will receive user inputs.
		return array(
			//array('pid', 'required'),
			array('pid', 'numerical', 'integerOnly'=>true),
			array('name, fids, first_letter', 'length', 'max'=>30),
			// The following rule is used by search().
			// Please remove those attributes that should not be searched.
			array('area_id, name, pid, fids, first_letter', 'safe', 'on'=>'search'),
		);
	}

	/**
	 * @return array relational rules.
	 */
	public function relations()
	{
		// NOTE: you may need to adjust the relation name and the related
		// class name for the relations automatically generated below.
		return array(
		);
	}

	/**
	 * @return array customized attribute labels (name=>label)
	 */
	public function attributeLabels()
	{
		return array(
			'area_id' => '区域ID',
			'name' => '区域名',
			'pid' => '上级ID',
			'fids' => '所有层级',
            'recommend_id' => '推荐',
			'first_letter' => '简拼',
            'level' => '所在级数',
            'type' => '类型'
		);
	}

	/**
	 * Retrieves a list of models based on the current search/filter conditions.
	 * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.
	 */
	public function search()
	{
		// Warning: Please modify the following code to remove attributes that
		// should not be searched.

		$criteria=new CDbCriteria;

		$criteria->compare('area_id',$this->area_id);
		$criteria->compare('name',$this->name,true);
		$criteria->compare('pid',$this->pid);
		$criteria->compare('fids',$this->fids,true);
		$criteria->compare('first_letter',$this->first_letter,true);

		return new CActiveDataProvider($this, array(
			'criteria'=>$criteria,
		));
	}
	
	/**
	 * 获取省
	 */
	public function getProvince() {
		$criteria =new CDbCriteria();
		$criteria->addInCondition('pid', array('0','-1'));
		return self::model()->findAll($criteria);
	}
	
	/**
	 * 生成对应JS
	 * @see DictJsCacheInterface::createJSFile()
	 */
	public function createJSFile() {
		//全部数据
		$data = Yii::app()->db->createCommand()->from($this->tableName())->select('area_id as id,name,pid')->queryAll();
		$tree = $this->getByOjbTree($data,'id','pid','_child',array('0','-1','-2'));
		//推荐城市
		$criteria=new CDbCriteria;
		$criteria->compare('recommend_id',1);
		$oRecommend = $this->findAll($criteria);
		$aRecommend = array();
		foreach($oRecommend as $val) {
			$aRecommend[$val['area_id']] = array('id'=>$val['area_id'],'name'=>$val['name']);
		}
		//生成全部数据
		$file = WEB_DIR . Yii::app()->params['dictJsPath'] . 'area.js';
		$json = CJSON::encode(array('all'=>$tree,'recommend'=>$aRecommend));
		$jsString = "fnCallback('fnArea',$json)";
		file_put_contents($file, $jsString);
		return true;
	}
	
	/**
	 * 获得一个多维数组
	 * @return unknown|Ambigous <multitype:unknown, multitype:array >
	 */
	public function getTree() {
		$mmkey = 'table_base_area_all_tree' . rand();
		if($mmData = Yii::app()->memcache->get($mmkey)) {
			return $mmData;
		}else	{
			$data = Yii::app()->db->createCommand()->from("{{base_area}}")->select('area_id,name,pid,fids')->queryAll();
			$tree = $this->getByOjbTree($data,'area_id','pid','_child',array('0','-1'));
			Yii::app()->memcache->set($mmkey,$tree);
			return $tree;
		}
	}
	/**
	 * 
	 * @param array $obj 需要生成树的对象或则数组
	 * @param string $pk 主键标示
	 * @param string $pid 父类标示
	 * @param string $child 子类小标
	 * @param array $root 根ID可以实现多种根ID如array('0','-1');
	 * @return multitype:unknown 多维数组
	 */	
	public function getByOjbTree($obj,$pk='id',$pid='pid',$child = '_child',$root=array('0'),$column='*') {
		// 创建Tree
		$tree = array();
		if(is_array($obj)) {
			// 创建基于主键的数组引用
			$refer = array();
			foreach ($obj as $key => $data) {
				$refer[$data[$pk]] =& $obj[$key];
			}
			foreach ($obj as $key => $data) {
				// 判断是否存在parent
				$parentId = $data[$pid];
				if (in_array($parentId,$root)) {
					$tree[$obj[$key][$pk]] =& $obj[$key];
				}else{
					if (isset($refer[$parentId])) {
						$parent =& $refer[$parentId];
						$parent[$child][$obj[$key][$pk]] =& $obj[$key];
					}
				}
			}
		}
		return $tree;
		
	}
	/**
	 * BaseAreaModel::listing() 获取所有列表
	 * 
	 * @return
	 */
	public function listing() {
		return self::model()->findAll(array('order'=>'fids ASC'));
	}
	/**
	 * BaseAreaModel::append() 添加新信息
	 * 
	 * @param mixed $data
	 * @return
	 */
	public function append($data) {
		$this->attributes=$data;
		$this->isNewRecord=true;
		$this->save();

		return count($this->errors)==0 && $this->change($this->attributes)?$this->area_id:0;
	}
	/**
	 * BaseAreaModel::change() 修改内容
	 * 
	 * @param mixed $data
	 * @return
	 */
	public function change($data) {
		$data['first_letter']=Yii::app()->common->getMoreFirstChar($data['name']);
		
		if(is_null(self::model()->findByPk($data['area_id']))) {
			array_shift($data);
			
			return $this->append($data);
		} else {
			$pfids=$this->fids($data['pid']);
			$fids=$this->fids($data['area_id']);
			$data['fids']=$pfids.$data['area_id'].',';
			
			$this->updateByPk($data['area_id'], $data);
			
			if(!$this->checkLevel($data, $pfids, $fids)) {
				$command=Yii::app()->db->createCommand('update '.$this->tableName().' set pid=SUBSTRING_INDEX(REPLACE(fids,CONCAT(\',\',area_id,\',\'),\'\'),\',\',-1),fids=replace(fids, \''.$fids.'\', \''.$data['fids'].'\') where area_id<>'.$data['area_id'].' and fids like \'%'.$fids.'%\'');
				$command->execute();
			}
			$this->createJSFile();
			return count($this->errors)==0;
		}
	}
	/**
	 * BaseAreaModel::checkLevel()
	 * 
	 * @param mixed $data
	 * @param mixed $pfids
	 * @param mixed $fids
	 * @return
	 */
	public function checkLevel($data, $pfids, $fids) {
		if($data['pid']<=0)	return true;
		if($data['pid']==$data['area_id']) return false;

		return is_null(self::model()->find('fids LIKE \'%'.$fids.'%\' AND area_id<>'.$data['area_id'].' AND area_id='.$data['pid']))?true:false;
	}
	/**
	 * BaseAreaModel::remove() 删除数据
	 * 
	 * @param mixed $data
	 * @return
	 */
	public function remove($area_id) {
		$fids=$this->fids($area_id);

		return $fids!=',' && self::model()->deleteAll('fids like \'%'.$fids.'%\'');
	}
	/**
	 * BaseAreaModel::fids() 获取关联ID
	 * 
	 * @param mixed $area_id
	 * @return
	 */
	private function fids($area_id) {
		$area=self::model()->findByPk($area_id);
		
		return is_null($area)?',':$area->fids;
	}	
	/**
	 * BaseAreaModel::getAreaName() 根据区域ID获取区域名称
	 * 
	 * @param mixed $area_id
	 * @return string 区域名称
	 */
	public static function getAreaName($area_id){
	    $model = BaseAreaModel::model()->findByPk((int)$area_id);
	    if(empty($model)) return '';
	    if(!empty($model->fids)){
    	    $fids=array_filter(explode(',', $model->fids));
    	    $fids=array_values($fids); 
    	    $area=array();
    	    if(!empty($fids)){
        	    $model2 = BaseAreaModel::model()->findAllByPk($fids);
        	    foreach ($model2 as $v){
        	        $area[]=$v->name;
        	    }
    	    }
    	    $area=join(',', $area);
	    }else{
	        $area=$model->name;
	    }
	   
	    return $area;
	}
}
